import React, { useState, useMemo, memo } from 'react'
import { Button } from 'antd'

const Children1 = (props) => {
  console.log('children1 rendering!!!')
  return (
    <p>double: {props.double}</p>
  )
}
const Children2 = (props) => {
  console.log('children2 rendering!!!')
  return (
    <p>double: {props.double}</p>
  )
}
// 被memo包装，当组件状态变化时渲染，作用类似类式组件里的PureComponent
const Children3 = memo((props) => {
  console.log('children3 rendering!!!')
  return (
    <p onClick={props.clickChildren}>double: {props.double}</p>
  )
})

const UseMemo = () => {
  const [count1, setCount1] = useState(0)
  const [count2, setCount2] = useState(0)
  const [count3, setCount3] = useState(0)
  const add1 = () => {
    setCount1(count1 + 1)
  }
  const add2 = () => {
    setCount2(count2 + 1)
  }
  const add3 = () => {
    setCount3(count3 + 1)
  }
  // 用useMemo包裹后获取唯一句柄，方法传入子组件，当父组件重新渲染时不会引起子组件重新传染，当useMemo第二个参数值改变时触发句柄变化导致子组件重新渲染
  // 下面语句可简写成useCallback(() => {alert('clickChildren')}, [])
  const clickChildren = useMemo(() => {
    return () => {
      alert('clickChildren')
    }
  }, [])
  // 第二个参数变化时执行第一个参数
  const double1 = useMemo(() => {
    return count2 * 2
  }, [count2])
  const double2 = useMemo(() => {
    return count3 * 3
  }, [count3 === 3])
  return (
    <>
      <div className='box'>
        <div className='box-header'>base</div>
        <div className='box-body'>
          <div className='box-content'>
            <p>count: {count1}</p>
            <Children1 double={1} />
            <p>
              <Button type='primary' onClick={add1}>add</Button>
            </p>
          </div>
        </div>
      </div>
      <div className='box'>
        <div className='box-header'>useMemo</div>
        <div className='box-body'>
          <div className='box-content'>
            <p>count: {count2}</p>
            <Children2 double={double1} />
            <p>
              <Button type='primary' onClick={add2}>add</Button>
            </p>
          </div>
        </div>
      </div>
      <div className='box'>
        <div className='box-header'>memo</div>
        <div className='box-body'>
          <div className='box-content'>
            <p>count: {count3}</p>
            <Children3 clickChildren={clickChildren} double={double2} />
            <p>
              <Button type='primary' onClick={add3}>add</Button>
            </p>
          </div>
        </div>
      </div>
    </>
  )
}
export default UseMemo